#include "qqmusic.h"
#include "ui_qqmusic.h"
#include <QPainter>
#include <QDebug>
#include <QCoreApplication>
#include <algorithm>
#include <QFileDialog>
#include <QTime>

QQMusic::QQMusic(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::QQMusic)
{
    ui->setupUi(this);

    initUi();
    initSqlite();
    initMusicList();
    initPlayer();
    connectSignalAndSlot();
}

QQMusic::~QQMusic()
{
    delete ui;
}

void QQMusic::initUi()
{
    // 无边框 + 背景透明
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
    setAttribute(Qt::WA_TranslucentBackground);

    //设置图标
    setWindowIcon(QIcon(":/images/tubiao.png"));

    //禁止最大化按钮
    ui->max->setEnabled(false);

    //设置左上角logo
    QPixmap pixmap_logo(":/images/logo.png");
    pixmap_logo = pixmap_logo.scaled(250, 150, Qt::KeepAspectRatio, Qt::SmoothTransformation);//设置图片缩放, 保持纵横比
    ui->logo->setPixmap(pixmap_logo);
    ui->logo->setAlignment(Qt::AlignCenter);  // 居中
    ui->logo->setScaledContents(false);       // 不拉伸变形

    //设置QLabel字体格式
    QFont font;
    font.setFamily("Microsoft YaHei"); // 字体名（可换成“微软雅黑”、“SimSun”等）
    font.setPixelSize(12);             // 字体大小（像素）
    font.setBold(false);                // 是否加粗
    ui->myMusicText->setFont(font);
    ui->onlineMusicText->setFont(font);
    ui->currentTime->setFont(font);
    ui->endTime->setFont(font);
    ui->musicNameAndSinger->setFont(font);

    //haedright按钮设置
    //按钮无边框 , 悬停颜色设置
    ui->settingBox->setStyleSheet("QPushButton{ border:none }; QPushButton:hover{ background-color:rgb(255,0,0) }");
    //设置右上角skin按钮
    ui->skin->setIcon(QIcon(":/images/skin.png"));
    //设置右上角min按钮
    ui->min->setIcon(QIcon(":/images/min.png"));
    //设置右上角max按钮
    ui->max->setIcon(QIcon(":/images/max.png"));
    //设置右上角quit按钮
    ui->quit->setIcon(QIcon(":/images/quit.png"));

    //设置bodyRight Play2按钮
    ui->controlBox->setStyleSheet("QPushButton{ border:none }");
    ui->play2->setStyleSheet("QPushButton:hover {background-color: rgba(227,227,227,0.5)}");//设置鼠标悬停颜色
    //播放模式图片
    ui->playMod->setIcon(QIcon(":/images/loopPlay.png"));
    ui->playMod->setToolTip("列表循环");
    //上一曲图片
    ui->playUp->setIcon(QIcon(":/images/up_page.png"));
    //下一曲图片
    ui->playDown->setIcon(QIcon(":/images/down_page.png"));
    //播放/暂停图片
    ui->play->setStyleSheet("QPushButton{border-radius: 20px}");
    ui->play->setIconSize(QSize(30,30));
    ui->play->setIcon(QIcon(":/images/start.png"));
    //音量调节图片
    ui->volumn->setIcon(QPixmap(":/images/volumn.png"));
    //添加音乐图片
    ui->addLocal->setIcon(QIcon(":/images/addLocal.png"));

    //设置btform图标和文本 , 并关联页面
    ui->rec->setIconAndTextAndPage(":/images/rec.png","推荐",0);
    ui->audio->setIconAndTextAndPage(":/images/audio.png","电台",1);
    ui->music->setIconAndTextAndPage(":/images/music.png","音乐馆",2);
    ui->like->setIconAndTextAndPage(":/images/like.png","我喜欢",3);
    ui->local->setIconAndTextAndPage(":/images/local.png","本地下载",4);
    ui->recent->setIconAndTextAndPage(":/images/recent.png","最近播放",5);

    //默认显示推荐页面 , 显示推荐按钮动画  , 推荐按钮默认选中
    ui->rec->showAnimal();
    ui->rec->setBackground();
    ui->stackedWidget->setCurrentIndex(0);

    //设置Rec的推荐页面
    srand(time(nullptr));//随机种子
    QVector<QPair<QString,QString>> pic = randmoPiction();
    QVector<QPair<QString,QString>> pic1(pic.begin(),pic.begin()+8);//前八张图片给recMusicBox
    QVector<QPair<QString,QString>> pic2(pic.begin()+8,pic.end());//后面的给supplyMusicBox
    ui->recMusicBox->setRecBoxItem(pic1,1,4);
    ui->supplyMusicBox->setRecBoxItem(pic2,2,4);
    ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 隐藏水平滚动条

    //设置我喜欢页面
    ui->likePage->setCommonPageUi("我喜欢",":/images/likePage.png");
    ui->likePage->setCommonPageType(LIKE_PAGE);
    //设置本地下载页面
    ui->localPage->setCommonPageUi("本地下载",":/images/localPage.png");
    ui->localPage->setCommonPageType(LOCAL_PAGE);
    //设置最近播放页面
    ui->recentPage->setCommonPageUi("最近播放",":/images/recentPage.png");
    ui->recentPage->setCommonPageType(RECENT_PAGE);

    //创建音量调解框对象
    volumeTool = new VolumeTool(this);

    //没有音乐 , 进度条默认不能拖拽, 点击
    ui->processBar->setEnabled(false);

    //创建歌词显示页面
    lrcPage = new LrcPage(this);
    lrcPage->hide();

    //初始化歌词界面上移动画对象
    lrcPageAnimal = new QPropertyAnimation(lrcPage,"geometry",this);
    lrcPageAnimal->setDuration(250);
    lrcPageAnimal->setStartValue(QRect(0,lrcPage->height(),lrcPage->width(),lrcPage->height()));
    lrcPageAnimal->setEndValue(QRect(0,0,lrcPage->width(),lrcPage->height()));
}

void QQMusic::initPlayer()
{
    //设置播放模式
    this->playList.setPlaybackMode(QMediaPlaylist::Loop);
    //设置初始音量20%
    this->player.setVolume(20);
    //设置播放列表
    this->player.setPlaylist(&playList);
    //默认正在播放的页面
    this->currentPage = ui->localPage;
    ui->localPage->addMusicToPlaylist(playList);
    //正在播放的歌曲默认
    this->currentMusic = nullptr;

    //音量调节滑块处理
    connect(this->volumeTool,&VolumeTool::setMusicVolume,this,&QQMusic::setPlayerVolume);

    //关联音量调节中 静音按钮处理
    connect(this->volumeTool,&VolumeTool::silenceBtnSignal,this,[&](bool isSilence){
        player.setMuted(isSilence);
        if(isSilence){
            ui->volumn->setIcon(QIcon(":/images/silence.png"));
        }else{
            ui->volumn->setIcon(QIcon(":/images/volumn.png"));
        }
    });

    //拦截player播放状态改变信号, 进行play按钮图片切换
    connect(&player,&QMediaPlayer::stateChanged,this,[&](){
        //播放状态改变 , 已经加载歌曲了, 进度条可拖动,点击
        ui->processBar->setEnabled(true);
        //根据播放状态更新新图片
        if(player.state() == QMediaPlayer::PlayingState){
            ui->play->setIcon(QIcon(":/images/stop.png"));
        }else{
            ui->play->setIcon(QIcon(":/images/start.png"));
        }
    });

    //拦截playList的播放源切换信号 , 改变音乐history属性 , 更新底部控制栏歌曲信息展示
    connect(&playList,&QMediaPlaylist::currentIndexChanged,this,[&](int idx){
        Music* music = currentPage->getMusic(idx);
        if(music){
            //1. 改变当前正在播放的歌曲
            currentMusic = music;
            //2. 更改history
            music->setIsHistory(true);
            //3. 更新歌曲结束时间显示
            qint64 time_ = music->getSongTime();
            QString show_time=QTime(0, 0).addSecs(time_/1000).toString(QString::fromLatin1("mm:ss"));
            ui->endTime->setText(show_time);
            //4. 更新底部歌曲名称 / 歌手名称
            ui->musicNameAndSinger->setText(music->getName() + " - " + music->getSinger());
            //5. 更新底部歌曲图片
            QVariant coverimage = player.metaData("ThumbnailImage");
            if(coverimage.isValid())
            {
                QImage image = coverimage.value<QImage>();
                ui->musicCover->setPixmap(QPixmap::fromImage(image));
            }
            else
            {
                //设置默认图片
                ui->musicCover->setPixmap(QPixmap(":/images/rec/026.png"));
            }
            ui->musicCover->setScaledContents(true);//自动填充
            //6. 解析歌词
            lrcPage->clearLrcWord();//清空上一曲歌的歌词
            QString lrcPath = music->getLrcFilePath();
            lrcPage->parseLrcFile(lrcPath);
            lrcPage->setMusicName(music->getName());
            lrcPage->setMusicSinger(music->getSinger());
        }
        //7. 刷新历史播放页面的歌曲列表
        ui->recentPage->reFresh(musicList);
    });

    //拦截player播放时间改变 , 动态更新当前播放的时间
    connect(&player,&QMediaPlayer::positionChanged,this,[&](qint64 position){
        //更新播放时间
        QString show_time=QTime(0, 0).addSecs(position/1000).toString(QString::fromLatin1("mm:ss"));
        ui->currentTime->setText(show_time);
        //更新进度条
        ui->processBar->setStep((float)position/currentMusic->getSongTime());
        //更新lrcPage歌词界面歌词
        lrcPage->showLrcWord(position);
    });

    //播放进度条拖拽点击 ----> 调整歌曲进度
    connect(ui->processBar,&MusicSlider::setMusicSlider,this,[&](float ration){
        player.setPosition(currentMusic->getSongTime()*ration);
    });
}

QVector<QPair<QString,QString>> QQMusic::randmoPiction()
{
    QVector<QPair<QString,QString>> pic = { {"001.png","当旋律响起,时光倒流,青春在一首首周杰伦的歌里重生"},
                                            {"002.png","他唱的不是情歌,而是我们最难忘的岁月"},
                                            {"003.png","他用节奏写下未来,这是他的音乐宇宙"},
                                            {"004.png","那些年听不懂的歌词,如今都成了人生的答案"},
                                            {"005.png","安静的夜 他的声音是最柔软的梦前序曲"},
                                            {"006.png","当钢琴声响起,夜色也有了温度。"},
                                            {"007.png","他让 R&B 在中文世界有了灵魂"},
                                            {"008.png","他用独特的腔调唱尽爱情的模样,每个音符都藏着温柔"},
                                            {"009.png","周杰伦,让古典与流行完美相遇"},
                                            {"010.png","在悠闲的午后,让周杰伦的旋律成为生活最甜的一口"},
                                            {"011.png","不是去拥抱,而是轻轻托着不让她受伤"},
                                            {"012.png","世界很安静,但心跳一直在线"},
                                            {"013.png","渺小的心,也装着想去拥抱世界的勇气"},
                                            {"014.png","每个平凡的瞬间,都在组成独一无二的奇迹"},
                                            {"015.png","念念不忘的, 从不是那个人, 而是那段再也回不去的时光"},
                                            {"016.png","让人情不自禁的英文歌"},
                                            {"017.png","效率加倍 | 学习工作专属轻音乐"},
                                            {"018.png","欧美音乐控 | 每首都值得心动循环"},
                                            {"019.png","暑前街少年"},
                                            {"020.png","泉水何其清澈 | 我以漫步踟躇"},
                                            {"021.png","“那些听不见音乐的人认为那些跳舞的人疯了”"},
                                            {"022.png","速度70迈 把车开到美国迈阿密"},
                                            {"023.png","谢谢你 在这世界的角落 发现了我"},
                                            {"024.png","在所有人事已非的景色里，我最喜欢你"},
                                            {"025.png","我曾经失落失望，失掉所有方向"},
                                            {"026.png","秋刀鱼的滋味，猫跟我都想了解"},
                                            {"027.png","如果世界漆黑，其实我很美"},
                                            {"028.png","不信命，只信双手去苦拼"},
                                            {"029.png","想关上这城市所有的灯光，黑暗中专心闻你的发香"},
                                            {"030.png","月光下，誓言开始坦诚相对"},
                                            {"031.png","确认过眼神 我遇上对的人"},
                                            {"032.png","但故事的最后你好像还是说了拜拜"}
                                        };
    //随机重排
    std::random_shuffle(pic.begin(),pic.end());
    return pic;
}

void QQMusic::initSqlite()
{
    //1. 数据库驱动加载
    sqlite = QSqlDatabase::addDatabase("QSQLITE");
    //2. 设置数据库名称
    sqlite.setDatabaseName("QQMusicDB.db");
    //3. 打开数据库
    if(!sqlite.open()){
        QMessageBox::critical(this,"QQMusicfo","数据库打开失败");
        return;
    }
    //4. 创建表
    QString sql = "CREATE TABLE IF NOT EXISTS QQMusicInfo(\
                    id INTEGER PRIMARY KEY AUTOINCREMENT,\
                    musicId VARCHAR(50) UNIQUE,\
                    musicName varchar(50),\
                    musicSinger varchar(50),\
                    musicAlbum varchar(50),\
                    musicUrl varchar(256),\
                    duration BIGINT,\
                    isLike INTEGER,\
                    isHistory INTEGER)";

    QSqlQuery query;
    if(!query.exec(sql)){
        QMessageBox::critical(this,"QQMusic","初始化错误");
        return;
    }
}

void QQMusic::initMusicList()
{
    musicList.readMusicFromDB();
    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}

void QQMusic::connectSignalAndSlot()
{
    //关联btForm的点击信号 和 处理信号的槽函数
    connect(ui->rec,&BtForm::btFormClick,this,&QQMusic::onBtFormClick);
    connect(ui->audio,&BtForm::btFormClick,this,&QQMusic::onBtFormClick);
    connect(ui->music,&BtForm::btFormClick,this,&QQMusic::onBtFormClick);
    connect(ui->like,&BtForm::btFormClick,this,&QQMusic::onBtFormClick);
    connect(ui->local,&BtForm::btFormClick,this,&QQMusic::onBtFormClick);
    connect(ui->recent,&BtForm::btFormClick,this,&QQMusic::onBtFormClick);

    //收藏按钮槽函数链接
    connect(ui->likePage,&CommonPage::updateLikeMusic,this,&QQMusic::updateLikeMusicAndPage);
    connect(ui->localPage,&CommonPage::updateLikeMusic,this,&QQMusic::updateLikeMusicAndPage);
    connect(ui->recentPage,&CommonPage::updateLikeMusic,this,&QQMusic::updateLikeMusicAndPage);

    //播放所有按钮信号拦截
    auto playAllFun = [&](CommonPage* page){
        //切换正在播放的页面
        this->currentPage = page;
        //重新获取该页面的歌曲列表 到 播放列表
        page->addMusicToPlaylist(this->playList);
        player.play();
    };
    connect(ui->likePage,&CommonPage::playAllSignal,this,playAllFun);
    connect(ui->localPage,&CommonPage::playAllSignal,this,playAllFun);
    connect(ui->recentPage,&CommonPage::playAllSignal,this,playAllFun);

    //页面歌曲双击信号拦截
    auto doubleClickedPlay = [&](CommonPage* page,int idx){
        //切换正在播放的页面
        this->currentPage = page;
        page->addMusicToPlaylist(playList);
        playList.setCurrentIndex(idx);
        player.play();
    };
    connect(ui->likePage,&CommonPage::musicListDoubleClicked,this,doubleClickedPlay);
    connect(ui->localPage,&CommonPage::musicListDoubleClicked,this,doubleClickedPlay);
    connect(ui->recentPage,&CommonPage::musicListDoubleClicked,this,doubleClickedPlay);
}

void QQMusic::mousePressEvent(QMouseEvent *event)
{
    //鼠标左键按下 , 计算相对位置
    if(event->button() == Qt::LeftButton){
        dragPos = event->globalPos() - geometry().topLeft();
    }
    QWidget::mousePressEvent(event);
}

void QQMusic::mouseMoveEvent(QMouseEvent *event)
{
    //在head区域内才移动
    if((event->buttons() & Qt::LeftButton) && (dragPos.y()<=ui->head->height())){
        this->move(event->globalPos() - dragPos);
    }
    QWidget::mouseMoveEvent(event);
}

void QQMusic::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QColor bgColor("#F0F0F0");  // 背景色
    painter.setBrush(bgColor);
    painter.setPen(Qt::NoPen);

    QRect rect = this->rect();
    painter.drawRoundedRect(rect, 7, 7); // 圆角半径
}

void QQMusic::on_quit_clicked()
{
    //写入歌曲状态到数据库
    musicList.addMusicToDB();
    //断开数据库
    sqlite.close();
    close();
}

void QQMusic::on_play_clicked()
{
    if((player.state() == QMediaPlayer::PausedState) || (player.state() == QMediaPlayer::StoppedState))
    {
        //当前处于暂停状态 --> 播放状态
        player.play();
    }
    else if(player.state() == QMediaPlayer::PlayingState)
    {
        //当前处于播放状态 ----> 暂停状态
        player.pause();
    }
    else
    {
        qDebug() << player.errorString();
    }
}

void QQMusic::onBtFormClick(const int pageId)
{
    //层叠页面切换
    ui->stackedWidget->setCurrentIndex(pageId);
    QList<BtForm*> btFormList = this->findChildren<BtForm*>();
    for(auto& btform:btFormList){
        if(btform->getPageId() != pageId){
            //清除背景色 , 隐藏动画
            btform->clearBackground();
            btform->hideAnimal();
        }else{
            //显示动画
            btform->showAnimal();
        }
    }
}

void QQMusic::on_volumn_clicked()
{
    QPoint point = ui->volumn->mapToGlobal(QPoint(0,0));
    QPoint pit = point - QPoint((volumeTool->width() - ui->volumn->width())/2, volumeTool->height());
    volumeTool->move(pit);
    volumeTool->show();
}


void QQMusic::on_addLocal_clicked()
{
    QFileDialog fileDialog(this);
    //设置标题
    fileDialog.setWindowTitle("添加本地音乐");

    //设置打开文件的默认路径
    QDir dir(QDir::currentPath());
    dir.cdUp();
    dir.cdUp();
    fileDialog.setDirectory(dir.path()+"/music");

    //设置一次打开多个
    fileDialog.setFileMode(QFileDialog::ExistingFiles);

    //设置文件过滤器
    //fileDialog.setNameFilter("代码文件(*.c *.cc *.cpp *.h *.hpp)");
    fileDialog.setNameFilter("音频文件(*.ogg *.flac *.wav *.mp3 *.aac *.mpeg)");

    //添加选中音频
    if(QFileDialog::Accepted == fileDialog.exec()){
        //获取选择的音频文件 Url列表
        QList<QUrl> fileUrls = fileDialog.selectedUrls();
        //根据Url列表创建musicList
        musicList.addMusicsByUrl(fileUrls);
        ui->localPage->reFresh(musicList);
        ui->localPage->addMusicToPlaylist(playList);
    }
}


void QQMusic::on_playMod_clicked()
{
    if(playList.playbackMode() == QMediaPlaylist::Loop)
    {
        ui->playMod->setIcon(QIcon(":/images/shuffle.png"));
        ui->playMod->setToolTip("随机播放");
        playList.setPlaybackMode(QMediaPlaylist::Random);
    }
    else if(playList.playbackMode() == QMediaPlaylist::Random)
    {
        ui->playMod->setIcon(QIcon(":/images/onePlay.png"));
        ui->playMod->setToolTip("单曲循环");
        playList.setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
    }
    else if(playList.playbackMode() == QMediaPlaylist::CurrentItemOnce)
    {
        ui->playMod->setIcon(QIcon(":/images/loopPlay.png"));
        ui->playMod->setToolTip("列表循环");
        playList.setPlaybackMode(QMediaPlaylist::Loop);
    }
}


void QQMusic::updateLikeMusicAndPage()
{
    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}


void QQMusic::on_min_clicked()
{
    this->showMinimized();
}


void QQMusic::on_playUp_clicked()
{
    playList.previous();
    player.play();
}


void QQMusic::on_playDown_clicked()
{
    playList.next();
    player.play();
}

void QQMusic::setPlayerVolume(int vol)
{
    player.setVolume(vol);
}


void QQMusic::on_lrcBtn_clicked()
{
    lrcPage->show();
    lrcPageAnimal->start();
}


void QQMusic::on_skin_clicked()
{
    //setStyleSheet("background-color: #000000");
}

